#include <linux/errno.h>
#include <linux/fs2.h>

static struct file_system_type *file_systems;

static struct file_system_type **find_filesystem(const char *name, unsigned len)
{
	struct file_system_type **p;
	for (p=&file_systems; *p; p=&(*p)->next)
		if (strlen((*p)->name) == len &&
		    strncmp((*p)->name, name, len) == 0)
			break;
	return p;
}

int register_filesystem(struct file_system_type * fs)
{
	int res = 0;
	struct file_system_type ** p;

	// BUG_ON(strchr(fs->name, '.'));
	if (fs->next)
		return -EBUSY;
	INIT_LIST_HEAD(&fs->fs_supers);
	// write_lock(&file_systems_lock);
	p = find_filesystem(fs->name, strlen(fs->name));
	if (*p)
		res = -EBUSY;
	else
		*p = fs;
	// write_unlock(&file_systems_lock);
	return res;
}

static struct file_system_type *__get_fs_type(const char *name, int len)
{
	struct file_system_type *fs;

	// read_lock(&file_systems_lock);
	fs = *(find_filesystem(name, len));
	// if (fs && !try_module_get(fs->owner))
		// fs = NULL;
	// read_unlock(&file_systems_lock);
	return fs;
}

struct file_system_type *get_fs_type(const char *name)
{
	struct file_system_type *fs;
	const char *dot = strchr(name, '.');
	int len = dot ? dot - name : strlen(name);

	fs = __get_fs_type(name, len);
	// if (!fs && (request_module("%.*s", len, name) == 0))
	// 	fs = __get_fs_type(name, len);

	// if (dot && fs && !(fs->fs_flags & FS_HAS_SUBTYPE)) {
	// 	put_filesystem(fs);
	// 	fs = NULL;
	// }
	return fs;
}
